package com.njworkorder.Controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.njworkorder.DTO.InspectionRegistrationAddDto;
import com.njworkorder.DTO.SelectDTO.SelectIRDto;
import com.njworkorder.Mapper.IrApMapper;
import com.njworkorder.Service.DiseaseRegistrationService;
import com.njworkorder.VO.ApShortInfo;
import com.njworkorder.VO.InspectionRegistrationListVo;
import com.njworkorder.Entity.*;
import com.njworkorder.Mapper.InspectionRegistrationMapper;
import com.njworkorder.Service.InspectionRegistrationService;
import com.njworkorder.Utils.Result;
import com.njworkorder.Utils.ResultUtil;
import com.njworkorder.VO.IrApVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Tag(name = "巡查管理", description = "巡查管理相关接口")
@RestController
@RequestMapping("/inspectionRegistration")
public class InspectionRegistrationController {

    private final InspectionRegistrationService inspectionRegistrationService;
    private final InspectionRegistrationMapper inspectionRegistrationMapper;
    private final IrApMapper irApMapper;
    private final DiseaseRegistrationService diseaseRegistrationService;

    public InspectionRegistrationController(InspectionRegistrationService inspectionRegistrationService, InspectionRegistrationMapper inspectionRegistrationMapper,
                                            IrApMapper irApMapper,DiseaseRegistrationService diseaseRegistrationService) {
        this.inspectionRegistrationService = inspectionRegistrationService;
        this.inspectionRegistrationMapper = inspectionRegistrationMapper;
        this.irApMapper = irApMapper;
        this.diseaseRegistrationService = diseaseRegistrationService;
    }

    @Operation(summary = "添加巡查登记信息")
    @PostMapping("/addInfo")
    public Result<String> addInfo(@RequestBody InspectionRegistrationAddDto irDTO,@RequestHeader("Create-Ap-Id") String createApId) {

        String irId = UUID.randomUUID().toString();

        List<String> apIds = irDTO.getApIds();
        List<IrAp> irApList = new ArrayList<>();
        IrAp irAp;
        for (String apId : apIds) {
            irAp = new IrAp();
            irAp.setIrId(irId);
            irAp.setApId(apId);
            irApList.add(irAp);
        }
        irApMapper.insert(irApList);

        InspectionRegistration ir = new InspectionRegistration();
        BeanUtils.copyProperties(irDTO, ir);
        ir.setId(irId);
        ir.setCreateApId(createApId);

        boolean save = inspectionRegistrationService.save(ir);
        if(save)
        {
            return ResultUtil.success("添加成功");
        }
        return ResultUtil.fail("添加失败");
    }

    @Operation(summary = "根据id修改巡查登记信息")
    @PostMapping("/updateInfo/{id}")
    public Result<String> updateInfo(@RequestBody InspectionRegistrationAddDto irDTO, @PathVariable("id") String id) {

        LambdaQueryWrapper<IrAp> queryWrapper = new LambdaQueryWrapper<IrAp>()
                .eq(IrAp::getIrId, id);
        irApMapper.delete(queryWrapper);

        InspectionRegistration ir = new InspectionRegistration();
        BeanUtils.copyProperties(irDTO,ir);
        ir.setId(id);
        boolean update = inspectionRegistrationService.updateById(ir);
        if(update){

            List<IrAp> irApList = new ArrayList<>();
            IrAp irAp;
            for (String apId : irDTO.getApIds()) {
                irAp = new IrAp();
                irAp.setIrId(id);
                irAp.setApId(apId);
                irApList.add(irAp);
            }
            irApMapper.insert(irApList);

            return ResultUtil.success("修改成功");
        }
        return ResultUtil.fail("修改失败");
    }

    @Operation(summary = "根据id删除巡查登记信息")
    @PostMapping("/deleteById")
    public Result<String> deleteById(@RequestParam("id") String id) {
        boolean delete = inspectionRegistrationService.removeById(id);
        if(delete){
            LambdaQueryWrapper<DiseaseRegistration> wrapper = new LambdaQueryWrapper<DiseaseRegistration>()
                    .eq(DiseaseRegistration::getInspectionRegistrationId,id);
            diseaseRegistrationService.remove(wrapper);

            LambdaQueryWrapper<IrAp> queryWrapper = new LambdaQueryWrapper<IrAp>()
                    .eq(IrAp::getIrId, id);
            irApMapper.delete(queryWrapper);

            return ResultUtil.success("删除成功");
        }
        return ResultUtil.fail("删除失败");
    }

    @Operation(summary = "根据id查询巡查登记信息")
    @PostMapping("/getById")
    public Result<InspectionRegistrationListVo> getById(@RequestParam("id") String id) {

        MPJLambdaWrapper<InspectionRegistration> wrapper = new MPJLambdaWrapper<InspectionRegistration>()
                .selectAll(InspectionRegistration.class)
                .select(Workspace::getWorkspaceName)
                .select(InspectionCar::getCarNum)
                .select(Section::getSectionName)
                .eq(InspectionRegistration::getId, id)
                .leftJoin(Workspace.class, Workspace::getId, InspectionRegistration::getWorkspaceId)
                .leftJoin(InspectionCar.class, InspectionCar::getId, InspectionRegistration::getInspectionCarId)
                .leftJoin(Section.class, Section::getId, InspectionRegistration::getSectionId)
                .leftJoin(Route.class, Route::getId, Section::getRouteId,ext ->
                        ext.selectAs(Route::getRouteName, InspectionRegistrationListVo::getRouteName)
                                .selectAs(Route::getId, InspectionRegistrationListVo::getRouteId));

        InspectionRegistrationListVo inspectionRegistrationListVo = inspectionRegistrationMapper.selectJoinOne(InspectionRegistrationListVo.class, wrapper);

        MPJLambdaWrapper<IrAp> wrapper1 = new MPJLambdaWrapper<IrAp>()
                .selectAll(IrAp.class)
                .leftJoin(AdministrativePersonnel.class,AdministrativePersonnel::getId, IrAp::getApId,ext->
                        ext.selectAs(AdministrativePersonnel::getName,IrApVo::getApName))
                .eq(IrAp::getIrId, id);
        List<IrApVo> irApVoList = irApMapper.selectJoinList(IrApVo.class, wrapper1);

        inspectionRegistrationListVo.setApShortInfos(getApShortInfoList(irApVoList));

        return ResultUtil.success(inspectionRegistrationListVo);
    }

    @Operation(summary = "获取巡查登记信息列表")
    @PostMapping("/getList")
    public Result<Page<InspectionRegistrationListVo>> getList(@RequestBody SelectIRDto selectIRDto) {

        MPJLambdaWrapper<InspectionRegistration> wrapper = new MPJLambdaWrapper<InspectionRegistration>()
                .selectAll(InspectionRegistration.class)
                .select(Workspace::getWorkspaceName)
                .select(InspectionCar::getCarNum)
                .select(Section::getSectionName)

                .leftJoin(Workspace.class, Workspace::getId, InspectionRegistration::getWorkspaceId)
                .leftJoin(InspectionCar.class, InspectionCar::getId, InspectionRegistration::getInspectionCarId)
                .leftJoin(Section.class, Section::getId, InspectionRegistration::getSectionId)
                .leftJoin(Route.class, Route::getId, Section::getRouteId,ext ->
                        ext.selectAs(Route::getRouteName, InspectionRegistrationListVo::getRouteName)
                                .selectAs(Route::getId, InspectionRegistrationListVo::getRouteId))

                .apply("1=1").eq(!selectIRDto.getInspectionType().isEmpty(),InspectionRegistration::getInspectionType,selectIRDto.getInspectionType())
                .ge(!selectIRDto.getStartTime().isEmpty(), InspectionRegistration::getInspectionStartTime, selectIRDto.getStartTime())
                .le(!selectIRDto.getEndTime().isEmpty(), InspectionRegistration::getInspectionEndTime, selectIRDto.getEndTime())
                .eq(StringUtils.isNotEmpty(selectIRDto.getWorkspaceId()),Workspace::getId,selectIRDto.getWorkspaceId())
                .orderByDesc(InspectionRegistration::getPublishTime);

        Page<InspectionRegistrationListVo> inspectionRegistrationListDTOPage = inspectionRegistrationMapper.selectJoinPage(new Page<>(selectIRDto.getPageIndex(), selectIRDto.getPageSize()), InspectionRegistrationListVo.class, wrapper);

        if(inspectionRegistrationListDTOPage.getTotal()>0){
            List<String> list = inspectionRegistrationListDTOPage.getRecords().stream().map(InspectionRegistrationListVo::getId).toList();
            MPJLambdaWrapper<IrAp> wrapper1 = new MPJLambdaWrapper<IrAp>()
                    .selectAll(IrAp.class)
                    .leftJoin(AdministrativePersonnel.class,AdministrativePersonnel::getId, IrAp::getApId,ext->
                            ext.selectAs(AdministrativePersonnel::getName,IrApVo::getApName))
                    .in(IrAp::getIrId,list);
            List<IrApVo> irApVoList = irApMapper.selectJoinList(IrApVo.class, wrapper1);

            for (InspectionRegistrationListVo item : inspectionRegistrationListDTOPage.getRecords()) {
                List<IrApVo> irApVoList1 = irApVoList.stream().filter(irApVo -> irApVo.getIrId().equals(item.getId())).toList();

                item.setApShortInfos(getApShortInfoList(irApVoList1));
            }
        }
        return ResultUtil.success(inspectionRegistrationListDTOPage);
    }

    private List<ApShortInfo> getApShortInfoList(List<IrApVo> irApVoList){
        List<ApShortInfo> apShortInfoList = new ArrayList<>();
        ApShortInfo apShortInfo;
        for (IrApVo irApVo : irApVoList) {
            apShortInfo = new ApShortInfo();
            BeanUtils.copyProperties(irApVo, apShortInfo);
            apShortInfoList.add(apShortInfo);
        }
        return apShortInfoList;
    }

    @Operation(summary = "获取巡查里程数")
    @GetMapping("/getInspectionMileage")
    public Result<List<Map<String,Object>>> getInspectionMileage(@RequestParam(value = "days",required = false,defaultValue = "7") int days){

        LocalDate now = LocalDate.now();
        LocalDate localDate1 = now.minusDays(days - 1);
        Date time = Date.from(localDate1.atStartOfDay(ZoneId.systemDefault()).toInstant());

        QueryWrapper<InspectionRegistration> wrapper = new QueryWrapper<InspectionRegistration>()
                .select("inspection_mileage","DATE_FORMAT(publish_time,'%Y-%m-%d') remark")
                .ge("publish_time", time);
        List<InspectionRegistration> list = inspectionRegistrationService.list(wrapper);

        List<Map<String,Object>> maps = new ArrayList<>();
        Map<String,Object> map;
        for(int i=1;i<days + 1;i++){
            String format = now.minusDays(days-i).format(DateTimeFormatter.ISO_LOCAL_DATE);
            List<InspectionRegistration> list1 = list.stream().filter(f -> f.getRemark().equals(format)).toList();
            if(list1.isEmpty()){
                map = new HashMap<>();
                map.put("publishTime",format);
                map.put("inspectionMileage",0);
            }else{
                map = new HashMap<>();
                map.put("publishTime",format);
                map.put("inspectionMileage",list1.stream().mapToDouble(InspectionRegistration::getInspectionMileage).sum());
            }
            maps.add(map);
        }
        return ResultUtil.success(maps);
    }

    @Operation(summary = "获取巡查任务数")
    @GetMapping("/getPatrolTasksNum")
    public Result<List<Map<String,Object>>> getPatrolTasksNum(@RequestParam(value = "days",required = false,defaultValue = "7") int days){

        LocalDate now = LocalDate.now();
        LocalDate localDate = now.minusDays(days - 1);
        Date time = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());

        MPJLambdaWrapper<InspectionRegistration> wrapper = new MPJLambdaWrapper<InspectionRegistration>()

                .selectAs(AssignmentWithDisease::getAssignmentId,InspectionRegistration::getWorkspaceId)
                .selectAs("DATE_FORMAT(t.publish_time,'%Y-%m-%d')",InspectionRegistration::getRemark)

                .leftJoin(DiseaseRegistration.class,DiseaseRegistration::getInspectionRegistrationId,InspectionRegistration::getId)
                .leftJoin(AssignmentWithDisease.class,AssignmentWithDisease::getDiseaseId,DiseaseRegistration::getId)
                .ge(InspectionRegistration::getPublishTime,time)
                .groupBy(AssignmentWithDisease::getAssignmentId);

        List<InspectionRegistration> inspectionRegistrations = inspectionRegistrationService.selectJoinList(InspectionRegistration.class, wrapper);

        List<Map<String,Object>> maps = new ArrayList<>();
        Map<String,Object> map;
        for(int i=1;i<days + 1;i++){
            String format = now.minusDays(days-i).format(DateTimeFormatter.ISO_LOCAL_DATE);
            List<InspectionRegistration> list = inspectionRegistrations.stream().filter(f -> f.getRemark().equals(format)).toList();

            if(list.isEmpty()){
                map = new HashMap<>();
                map.put("publishTime",format);
                map.put("count",0);
            }else{
                map = new HashMap<>();
                map.put("publishTime",format);
                map.put("count",list.size());
            }
            maps.add(map);
        }
        return ResultUtil.success(maps);
    }


}
